package com.cloudcentral.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.cloudcentral.entity.Detect;
import com.cloudcentral.entity.DetectStrategy;
import com.cloudcentral.entity.query.DetectQuery;
import com.cloudcentral.entity.vo.DetectDetailVO;
import com.cloudcentral.entity.vo.PageVO;
import com.cloudcentral.exception.FailureException;
import com.cloudcentral.mapper.DetectMapper;
import com.cloudcentral.mapper.DetectStrategyMapper;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 探测任务任务表 服务实现类
 * </p>
 *
 * @author Administrator
 * @since 2023-11-23
 */
@Service
public class DetectService extends ServiceImpl<DetectMapper, Detect> {
  private final RedissonClient redissonClient;
  private final DetectStrategyMapper detectStrategyMapper;

  @Autowired
  public DetectService(RedissonClient redissonClient, DetectStrategyMapper detectStrategyMapper) {
    this.redissonClient = redissonClient;
    this.detectStrategyMapper = detectStrategyMapper;
  }

  @Transactional(rollbackFor = {Exception.class})
  @GlobalTransactional(rollbackFor = {Exception.class})
  public Boolean submit(Detect detect) throws FailureException {
    if (StringUtils.isBlank(detect.getName())) throw new FailureException("缺少名称");
    else if (detect.getType() == null) throw new FailureException("缺少任务类型");
    else if (detect.getMasterId() == null) throw new FailureException("缺少主站ID");
    else if (detect.getSlaveId() == null) throw new FailureException("缺少从站ID");
    else {
      if (detect.getId() == null && save(detect)) {
        List<DetectStrategy> list = new ArrayList<>();
        for (int hour = 0; hour < 24; hour++) {
          DetectStrategy detectStrategy = DetectStrategy.builder().detectId(detect.getId()).hour(hour).power(0).params("").build();
          list.add(detectStrategy);
        }
        return SqlHelper.retBool(detectStrategyMapper.insertBatch(list));
      } else return updateById(detect);
    }
  }

  @Transactional(rollbackFor = {Exception.class})
  @GlobalTransactional(rollbackFor = {Exception.class})
  public Boolean delete(Long id) throws FailureException {
    RSet<Long> rSet = redissonClient.getSet("WS-Detect");
    if (rSet.contains(id)) throw new FailureException("任务正在执行中");
    else return removeById(id);
  }

  public PageVO<DetectDetailVO> listPage(DetectQuery query) {
    RSet<Long> rSet = redissonClient.getSet("WS-Detect");
    IPage<DetectDetailVO> iPage = baseMapper.listPage(new Page<>(query.getPage(), query.getSize()), query);
    return new PageVO<>(iPage.getRecords().stream().peek(detect -> {
      detect.setStatus(rSet.contains(detect.getId()));
      detect.setStrategy(detect.getStrategy().stream().map(strategy -> {
        DetectStrategy detectStrategy = JSON.parseObject(JSON.toJSONString(strategy), DetectStrategy.class);
        return detectStrategy.toJson();
      }).collect(Collectors.toList()));
    }).collect(Collectors.toList()), iPage.getTotal());
  }

  public DetectDetailVO selectDetailById(Long detectId) {
    RSet<Long> rSet = redissonClient.getSet("WS-Detect");
    DetectDetailVO detectDetailVO = baseMapper.selectDetailById(detectId);
    detectDetailVO.setStatus(rSet.contains(detectDetailVO.getId()));
    return detectDetailVO;
  }
}
